#include<iostream>
#include<math.h>


class function  //函数类
{
public:
    virtual double operator()(double _x) = 0;
    virtual double derivative(double _x) = 0;
};

class myfunc : function  //输入函数
{
private:
    double(*fp)(double);//f(x)  指针
    double(*dfp)(double);//f'(x) 指针  
public:
    myfunc(double (*_fp)(double)){fp=_fp;} //只输入函数
    myfunc(double (*_fp)(double), double(*_dfp)(double)){fp=_fp; dfp= _dfp;}//函数及其导数
    double operator()(double _x){return fp(_x);}
    double derivative(double _x){return dfp(_x);}
};

class equationsolver//求解器虚类  不得实体化 逻辑上规定基类
{
public:
    virtual double solve() = 0; //纯虚函数声明
};

class bisection : public equationsolver //二分法逻辑限制
{
private:
    double a;       //左端点
    double b;       //右端点
    double delta;   //
    double eps;     //机器误差
    int M;          //限度
    myfunc f;       //输入函数
public:
    bisection(double _a,double _b,double _delta,double _eps,int _M, myfunc _f);
    ~bisection(){};
    double solve();
};

//  类中函数传值
bisection::bisection(double _a,double _b,double _delta,double _eps,int _M, myfunc _f):
a(_a),b(_b),delta(_delta),eps(_eps),M(_M),f(_f){}

int sign(double x)      //符号函数
{
    if (x > 0)
        return 1;
    else if (x == 0)
        return 0;
    else
        return -1;
}

double bisection::solve()  //二分法主题函数
{
    double h=b-a;
    double u,c,w;
    for(int k = 1;k < M;k++){
        u = f(a);
        h /= 2;
        c = a + h;
        w=f(c);
        if(fabs(h) < delta || fabs(w) < eps) break;
        else if (sign(w)==sign(u)){     //sign符号函数
            a = c;
        }
    }
    return c;
}

class newton : public equationsolver  //牛顿法逻辑限制
{
private:
    double x;       //起始点
    double eps;     //允许误差
    int M;          //限度
    myfunc f;       //输入函数
public:
    newton(double _x, double _eps, int _M,myfunc _f);
    double solve();
};
 newton::newton(double _x,double _eps, int _M,myfunc _f):
x(_x), eps(_eps), M(_M), f(_f){}

double newton::solve()//牛顿法主体函数
{
    double u;
    for(int k = 0; k < M;k++){
        u = f(x);
        if(fabs(u) < eps) break;
        x -= u/f.derivative(x);
    }
    return x;
}

class secant : public equationsolver //割线法逻辑限制
{
private:
    double x0;      //割线端点0
    double x1;      //割线端点1
    double delta;   //精度
    double eps;     //允许误差
    int M;          //次数
    myfunc f;       //输入函数
public:
    secant(double _x0, double _x1, double _delta, double _eps, int _M,myfunc _f);
    double solve();
};

secant::secant(double _x0, double _x1, double _delta, double _eps, int _M ,myfunc _f):
x0(_x0), x1(_x1), delta(_delta), eps(_eps), M(_M), f(_f){}

void swap(double &x, double &y) //交换函数
{
    double z = x;
    x = y;
    y = z;
}


double secant::solve(){
    double u = f(x1);
    double v = f(x0);
    double k;
    int i;
    for (i = 2;i < M;i++ ){
        if(fabs(u) > fabs(v)){
            swap(x0,x1);    //交换函数
            swap(u,v);
        }
        k = (x1 - x0)/(u-v);
        x0 = x1;
        v = u;
        x1 -= u*k;
        u = f(x1);
        if (fabs(x1 -x0) < delta || fabs(u) < eps) break;
    }
    return x1;
}
///home/cheseven/mainsolver
